﻿#include <QCoreApplication>
#include"opencv.hpp"
using namespace cv;
using namespace std;

#include<iostream>
Point center;
RotatedRect center_ellipse_rect;

Mat getBigmask(Mat src){

  equalizeHist(src, src);
  threshold(src, src, 185, 255, 0);



  Mat hline = getStructuringElement(MORPH_RECT, Size(13, 13), Point(-1, -1));
  erode(src, src, hline);
  dilate(src, src, hline);



  Canny(src, src, 50, 200);



  Mat hline1 = getStructuringElement(MORPH_RECT, Size(13, 13), Point(-1, -1));
  dilate(src, src, hline1);

     std::vector<std::vector<cv::Point>> contours;
      std::vector<cv::Vec4i> hierarchy;
      Mat mask = Mat::zeros(src.rows,src.cols,src.type());
    //只输出最顶层轮廓
    findContours(src, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE, cv::Point());
    cv::RotatedRect ellipse_rect;
    for (int i = 0; i < contours.size(); i++)
    {

      if(contours[i].size() > 15)
      {
         ellipse_rect = fitEllipse(contours[i]);
         cv::Scalar color;
                 color = cv::Scalar(50,128,200);
         int w = ellipse_rect.size.width;
         int h = ellipse_rect.size.height;
         if(w<src.cols/3||h<src.rows/3)
           continue;
         ellipse(src, ellipse_rect, color, 2, 8);
         ellipse(mask, ellipse_rect, cv::Scalar(255,128,200), 2, 8);
         center_ellipse_rect = ellipse_rect;
      }
    }

    floodFill(mask, cv::Point(ellipse_rect.center.x, ellipse_rect.center.y), Scalar(255, 255, 255));
    return mask;
}


Mat getDragon(Mat src111){
  Mat src = src111.clone();
//  equalizeHist(src, src);
  threshold(src, src, 150, 255, 0);

//  namedWindow("threshold",WINDOW_FREERATIO);
//  imshow("threshold",src);

     std::vector<std::vector<cv::Point>> contours;
      std::vector<cv::Vec4i> hierarchy;

    findContours(src, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
    Mat src1 = Mat::zeros(src.rows,src.cols,CV_8UC3);
    Mat mask = Mat::zeros(src.rows,src.cols,CV_8UC1);
    std::cout<<(contours.size())<<endl;

    cv::RotatedRect ellipse_rect;
    for (int i = 0; i < contours.size(); i++)
    {

      if(contours[i].size() > 200)
      {
        if(contours[i].size() > 1000) continue;
        drawContours(src1, contours, i, cv::Scalar(128,0,128), 1, 8, hierarchy, 0);
         ellipse_rect = fitEllipse(contours[i]);
         cv::Scalar color;
         color = cv::Scalar(50,128,200);

        Moments  mo = moments(contours[i], false);

        Point moCenter = Point2f(mo.m10 / mo.m00, mo.m01 / mo.m00);

        int distant = abs(moCenter.y - center_ellipse_rect.center.y)+abs(moCenter.x - center_ellipse_rect.center.x);

        if (distant >center_ellipse_rect.size.height/3) continue;
        circle(src1, moCenter, 2, color,2);
        ellipse(src1, ellipse_rect, color, 2, 8);
        drawContours(mask, contours, i, cv::Scalar(255,0,128), 1, 8, hierarchy, 0);

      }
    }
    floodFill(mask, Point(0,0), Scalar(255, 255, 255));

    return ~mask;
}

Mat groupDragon(Mat src){
   Mat src1 = src.clone();
   Mat dilate_kel = getStructuringElement(MORPH_RECT, Size(50, 50), Point(-1, -1));
   Mat erode_kel = getStructuringElement(MORPH_RECT, Size(20, 20), Point(-1, -1));
   dilate(src1, src1, dilate_kel);
   erode(src1, src1, erode_kel);

   std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Vec4i> hierarchy;
   findContours(src1, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
   Mat mask = Mat::zeros(src1.rows,src1.cols,CV_8UC1);

   cv::RotatedRect ellipse_rect;
   vector<vector<Point>> convex(contours.size());
   for (int i = 0; i < contours.size(); i++)
   {
//        ellipse_rect = fitEllipse(contours[i]);
        cv::Scalar color;
        color = cv::Scalar(50,128,200);
        convexHull(contours[i], convex[i]);
        drawContours(mask, convex, i, Scalar(255, 255, 255), 2, 8);

       Moments  mo = moments(convex[i], false);

       Point moCenter = Point2f(mo.m10 / mo.m00, mo.m01 / mo.m00);
       floodFill(mask, moCenter, Scalar(255, 255, 255));

   }
     return mask;

}
Point char_center;
Mat del_char(Mat src){
  Mat Left =src.clone();
  threshold(Left, Left, 255, 255,THRESH_BINARY_INV| THRESH_OTSU);
//  namedWindow("big_src2",WINDOW_FREERATIO);
//  imshow("big_src2",Left);

  Mat Left1 = Left.clone();
  Mat dilate_kel = getStructuringElement(MORPH_RECT, Size(1, 30), Point(-1, -1));

  dilate(Left1, Left1, dilate_kel);
  Mat erode_kel = getStructuringElement(MORPH_RECT, Size(3, 15), Point(-1, -1));
  erode(Left1, Left1, erode_kel);

//  namedWindow("big_src3",WINDOW_FREERATIO);
//  imshow("big_src3",Left1);

  std::vector<std::vector<cv::Point>> contours;
   std::vector<cv::Vec4i> hierarchy;
  findContours(Left1, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
  Mat mask = Mat::zeros(Left1.rows,Left1.cols,CV_8UC1);
  Mat mask1 = Left.clone();
  cvtColor(mask1,mask1,COLOR_GRAY2BGR);


  cv::RotatedRect ellipse_rect;
  vector<vector<Point>> convex(contours.size());
  for (int i = 0; i < contours.size(); i++)
  {
//        ellipse_rect = fitEllipse(contours[i]);
    if( contours[i].size()<300){
      continue;
    }
    if(contourArea(contours[i])>100000)continue;;
       cv::Scalar color;
       color = cv::Scalar(50,128,200);
       convexHull(contours[i], convex[i]);
       drawContours(mask, contours, i, Scalar(255, 255, 255), 2, 8);

       drawContours(mask1, convex, i, Scalar(255, 0, 255), 2, 8);
       drawContours(mask1, contours, i, Scalar(255, 255, 0), 2, 8);

      Moments  mo = moments(contours[i], false);

      Point moCenter = Point2f(mo.m10 / mo.m00, mo.m01 / mo.m00);
      char_center =moCenter;
      floodFill(mask, moCenter, Scalar(255, 255, 255));

  }
//  namedWindow("Left1111",WINDOW_FREERATIO);
//  imshow("Left1111",mask1);
  namedWindow("del_char",WINDOW_FREERATIO);
  imshow("del_char",mask);
    return mask;

}
int main111(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);


  cv::Mat src = cv::imread("E:/workspace/qt/DaHeng/ng/ng03.bmp");

  resize(src,src,Size(src.cols*3,src.rows*3));
  namedWindow("src",WINDOW_FREERATIO);
  imshow("src",src);
  cvtColor(src, src, COLOR_BGR2GRAY);
  Mat ori = src.clone();

  //得到大圆
  Mat mask =   getBigmask(src);
  namedWindow("mask",WINDOW_FREERATIO);
  imshow("mask",mask);

   Mat big_src = ori & mask;
   namedWindow("big_src",WINDOW_FREERATIO);
   imshow("big_src",big_src);


    Mat big_src1 = big_src.clone();
   if (big_src1.channels() != 1) {
       cvtColor(big_src1, big_src1, COLOR_BGR2GRAY);
     }
     //blur(src, src, Size(3, 3));

    //去掉图案
    Mat center_dragon = getDragon(big_src);
    namedWindow("big_src",WINDOW_FREERATIO);
    imshow("big_src",big_src);
    namedWindow("center_dragon",WINDOW_FREERATIO);
    imshow("center_dragon",center_dragon);

    Mat group_dragon = groupDragon(center_dragon);
    namedWindow("group_dragon",WINDOW_FREERATIO);
    imshow("group_dragon",group_dragon);
    //
    Mat add_dragon;
    addWeighted(group_dragon,255,big_src,1,0,add_dragon);
    cout<<center_dragon.type()<<"  "<<big_src.type()<<endl;
//    Canny(add_dragon,add_dragon,20,100);
    namedWindow("add_dragon",WINDOW_FREERATIO);
    imshow("add_dragon",add_dragon);
    Mat origin = big_src.clone();
    imwrite("E:/workspace/qt/DaHeng/ng/add_dragonnew3.jpg",add_dragon);
    threshold(add_dragon, add_dragon, 150, 255, 0);
      Mat hline1 = getStructuringElement(MORPH_RECT, Size(20, 2), Point(-1, -1));
    //  dilate(dst, dst, hline1);
      erode(add_dragon, add_dragon, hline1);
     namedWindow("二值化图像",WINDOW_FREERATIO);
     imshow("二值化图像", ~add_dragon);

     Mat bbb = big_src-( ~add_dragon)-group_dragon;
     namedWindow("big_src-( ~add_dragon)",WINDOW_FREERATIO);
     imshow("big_src-( ~add_dragon)",bbb);


     std::vector<std::vector<cv::Point>> contours;
      std::vector<cv::Vec4i> hierarchy;
     findContours(bbb, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
     vector<cv::RotatedRect> ellipse_rect;
      vector<float> lens;
      vector<Rect> rect;
      Mat dst_mask = Mat::zeros(bbb.rows,bbb.cols,CV_8UC1);

     for (int i = 0; i < contours.size(); i++)
     {

       if(contours[i].size() > 30)
       {
         RotatedRect current  = fitEllipse(contours[i]);

         Moments  mo = moments(contours[i], false);

         Point moCenter = Point2f(mo.m10 / mo.m00, mo.m01 / mo.m00);
         if (contourArea(contours[i])<20) continue;
          cv::Scalar color;
                  color = cv::Scalar(50,128,200);
          float w = current.size.width;
          float h = current.size.height;
          float len = max(w,h);
          lens.push_back(len);
           if(abs(current.angle)<90){
             if (abs(current.angle)<10){
               cout<<current.angle<<"sjdhf";
               continue;
             }
           }/*else if(abs(current.angle-90)<5){
             cout<<current.angle<<"asdf";
             if (contourArea(contours[i])>500)
             continue;
           }*/
           ellipse_rect.push_back(current);
          drawContours(mask, contours, i,cv::Scalar(0,128,200), 1, 8);
          drawContours(dst_mask, contours, i,cv::Scalar(255,128,200), 1, 8);
   //       rect.push_back(boundingRect(contours[i]));
   //      floodFill(dst_mask,moCenter,cv::Scalar(255,128,200));
       }
     }
     namedWindow("moCenter",WINDOW_FREERATIO);
     imshow("moCenter", dst_mask);


//    //下半部分对比度增强
//    int x1 = center_ellipse_rect.center.x - center_ellipse_rect.size.width/2;
//    int x2 = center_ellipse_rect.center.x + center_ellipse_rect.size.width/2;
//    int y1 = center_ellipse_rect.center.y +center_ellipse_rect.size.height/9;
//    int y2 = center_ellipse_rect.center.y +center_ellipse_rect.size.height/2;
//    Rect box = Rect(Point(x1,y1),Point(x2,y2));

//    Mat down_ = add_dragon(box);
//    Mat down_1 = down_;
//    cout<<down_.channels();
//    uchar* p;
//    for (int i = 0; i < down_1.rows; i++)
//      {
//        p = down_1.ptr<uchar>(i);				//指向每一行首地址
//        for (int j = 0; j < down_1.cols; j++)
//        {
//          int wwww = 50;
//          int new1  = p[j] + int(wwww*(float)(i)/(float)down_.rows);
//          if(new1 <= 255)
//            p[j] = new1;					//反差处理
//        }
//    }

////    addWeighted(down_,1,down_,0,100,down_);
//    add_dragon = add_dragon& mask;
//    namedWindow("down_",WINDOW_FREERATIO);
//    imshow("down_",add_dragon);


//    add_dragon






//    imwrite("E:/workspace/qt/DaHeng/ng/add_dragon.jpg",add_dragon);






//////  Mat kernel = (Mat_<char>(7, 7) << -3,-2,-1, 0,1, 2,3,
//////                                     -3,-2,-1, 0,1, 2,3,
//////                                      -3,-2,-1, 0,1, 2,3,
//////                                     -3,-2,-1, 0,1, 2,3,
//////                -3,-2,-1, 0,1, 2,3,
//////                -3,-2,-1, 0,1, 2,3,

//////                                     -3,-2,-1, 0,1, 2,3);

////  Mat kernel = (Mat_<char>(3, 3) << -1, 0, 1,
////                     -2, 0, 2,
////                     -1, 0, 1);


////    filter2D(src, src,-1, kernel);
////    namedWindow("filter2D",WINDOW_FREERATIO);

////    cv::imshow("filter2D",src);
////    Mat hline1 = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
////    dilate(src, src, hline1);
////    namedWindow("dilate",WINDOW_FREERATIO);
////    cv::imshow("dilate",src);

//////  threshold(src, src, 0, 255, ThresholdTypes::THRESH_OTSU);
////  medianBlur(src,src,7);
////  threshold(src, src, 50, 255, THRESH_BINARY);
////  cv::imshow("threshold",src);
////      Mat hline = getStructuringElement(MORPH_CROSS, Size(3, 3), Point(-1, -1));
////      morphologyEx(src, src, MORPH_OPEN, hline);

//////    morphologyEx(src, src, MORPH_OPEN, hline);
//////    medianBlur(src,src,3);
//////    medianBlur(src,src,3);
//////    medianBlur(src,src,3);
////     cv::imshow("hline",src);

////////    Mat kernel1 = (Mat_<char>(3, 3) << -1, -4, -1,
////////                        0, 0, 0,
////////                        1, 4, 1);
////////      filter2D(src, src, -1, kernel1);
////////      medianBlur(src,src,3);


//////     Mat kernel1 = getStructuringElement(MORPH_RECT, Size(5, 1), Point(-1, -1));
////////     cvtColor(src,src,COLOR_GRAY2BGR);
//////       morphologyEx(src, src, MORPH_OPEN, kernel1);
//////       cv::imshow("src2",~src);
////////       cvtColor(src,src,COLOR_BGR2GRAY);
//////adaptiveThreshold(~src, src, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);

//////cv::imshow("src111",~src);

//////Canny(src, src,50,100);
////  if(src.empty()){
////    return 0;
////  }
////  cv::imshow("src",~src);
  cv::waitKey(0);


  return a.exec();
}


